home *** CD-ROM | disk | FTP | other *** search
/ Network Supervisor's Toolkit / Network Supervisor's Toolkit.iso / tools / nwtp06 / nwbindry.pas < prev    next >
Pascal/Delphi Source File  |  1996-07-10  |  51KB  |  1,443 lines

  1. {$X+,B-,V-,S-} {essential compiler directives}
  2.  
  3. UNIT nwBindry;
  4.  
  5. { nwBindry unit as of 950301 / NwTP 0.6 API. (c) 1993,1995, R.Spronk }
  6.  
  7. INTERFACE
  8.  
  9. USES nwIntr,nwMisc;
  10.  
  11. { Primary Functions:                    Interrupt: comments:
  12.  
  13. * AddBinderyObjectToSet                 (F217/41)
  14. * ChangeBinderyObjectPassword           (F217/40) Unencrypted Passwords.
  15. * ChangeEncrBinderyObjectPassword       (F217/4B) Encrypted Passwords.
  16. * ChangeBinderyObjectSecurity           (F217/38)
  17. * ChangePropertySecurity                (F217/3B)
  18. * CloseBindery                          (F217/44)
  19. * CreateBinderyObject                   (F217/32)
  20. * CreateProperty                        (F217/39)
  21. * DeleteBinderyObject                   (F217/33)
  22. * DeleteBinderyObjectFromSet            (F217/42)
  23. * DeleteProperty                        (F217/3A)
  24. * GetBinderyAccessLevel                 (F217/46)
  25. * GetBinderyObjectID                    (F217/35)
  26. * GetBinderyObjectName                  (F217/36)
  27. * GetEncryptionKey                      (F217/17) (1)
  28. * GetRelationOfBinderyObject            (F217/4C)
  29. * IsBinderyObjectInSet                  (F217/43)
  30. * IsStationAManager                     (F217/49)
  31. * OpenBindery                           (F217/45)
  32. * ReadPropertyValue                     (F217/3D)
  33. * RenameBinderyObject                   (F217/34)
  34. * ScanBinderyObject                     (F217/37)
  35. * ScanProperty                          (F217/3C)
  36. * VerifyBinderyObjectPassword           (F217/3F) Unencrypted Passwords.
  37. * VerifyEncrBinderyObjectPassword       (F217/4A) Encrypted passwords
  38. * WritePropertyValue                    (F217/3E)
  39.  
  40.   Secondary Functions:
  41.  
  42. * IsShellLoaded
  43. * IsUserLoggedOn
  44. * ExistsUser
  45. * ExistsFileServer
  46. * GetRealUserName
  47. * IsGroupMember
  48. * AddUserToGroup
  49. * DeleteUserFromGroup
  50.  
  51. Not implemented:
  52.  
  53. - ChangePassword                        (F217/01) (2)
  54. - GetMemberSetMofGroupG                 (F217/09) (3)
  55. - GetStationsRootMask                   (E3../06) (4)
  56. - MapNumberToGroupName                  (F217/08) (5)
  57. - MapNumberToObject                     (F217/04) (6)
  58. - MapObjectToNumber                     (F217/03) (7)
  59.  
  60. Notes: -Names of Objects & Properties (and Passwords) are converted to
  61.         uppercase by the above functions.
  62.        -Functions marked with a '*' are tested (with 3.1x) and found correct.
  63.         (See example programs in XBIND.ZIP, e.g. SCANBIND,TSTBIND,BACKBIN).
  64.        -(1): Called by other functions, e.g. ChangeEncrBinderObjectPassword,
  65.              VerifyEncrBinderyObjectPassword, LoginEncrToFileserver.
  66.         (2): This call has been replaced by F217/40 ChangeBinderyObjectPassword.
  67.         (3): replaced by F217/37 ScanBinderyObject and F217/3D ReadPropertyValue.
  68.         (4): -obsolete call-
  69.         (5,6): Replaced by F217/36 GetBinderyObjectName.
  70.         (7): Replaced by F217/35 GetBinderyObjectID.
  71. }
  72.  
  73. CONST
  74.  { known object types: (see the file OT_XXX for a full list)}
  75.   OT_WILD                        = Word(-1);
  76.   OT_UNKNOWN                     = 0;
  77.   OT_USER                        = 1;
  78.   OT_USER_GROUP                  = 2;
  79.   OT_PRINT_QUEUE                 = 3;
  80.   OT_FILE_SERVER                 = 4;
  81.   OT_JOB_SERVER                  = 5;
  82.   OT_GATEWAY                     = 6;
  83.   OT_PRINT_SERVER                = 7;
  84.   OT_ARCHIVE_QUEUE               = 8;
  85.   OT_ARCHIVE_SERVER              = 9;
  86.   OT_JOB_QUEUE                   = $0A;
  87.   OT_ADMINISTRATION              = $0B;
  88.   OT_ADVERTISING_PRINTSERVER     = $47;
  89.   OT_NETWARE_ACCESS_SERVER       = $98;
  90.   OT_NAMED_PIPES_SERVER          = $9A;
  91.   OT_RSPCX_SERVER                = $0107; { # Rconsole/FileServer, Sckt. 0451h, 8140h }
  92.  
  93.  { bindery security: }
  94.   BS_ANY_READ       = $00;
  95.   BS_LOGGED_READ    = $01;
  96.   BS_OBJECT_READ    = $02;
  97.   BS_SUPER_READ     = $03;
  98.   BS_BINDERY_READ   = $04;
  99.  
  100.   BS_ANY_WRITE      = $00;
  101.   BS_LOGGED_WRITE   = $10;
  102.   BS_OBJECT_WRITE   = $20;
  103.   BS_SUPER_WRITE    = $30;
  104.   BS_BINDERY_WRITE  = $40;
  105.  
  106. {property & object objFlag/propFlags Constants:}
  107.   BF_ITEM           = $00;
  108.   BF_SET            = $02;
  109.   BF_DYN_PROP       = $10; {1}
  110.   BF_STAT_PROP      = $00; {1}
  111.   { or BF_ITEM/SET with BF_xx_PROP to obtain propFlags }
  112.   BF_STAT_OBJ       = $00; {1}
  113.   BF_DYN_OBJ        = $01; {1}
  114.  
  115. { Note 1: not available in the NW interface for C }
  116.  
  117.  
  118. Type Tproperty=Array[1..128] of Byte;
  119.  
  120.      TobjIdArray=array[1..$20] of Longint;
  121.  
  122. Var result:word;
  123.  
  124. {F217/32 [2.15c+] }
  125. Function CreateBinderyObject(objName:string; objType:Word;
  126.                              objFlaG, objSecurity :Byte   ):boolean;
  127. { Creates an object in the bindery. }
  128.  
  129. {F217/33 [2.15c+] }
  130. Function DeleteBinderyObject( objName:String; objType:Word ):boolean;
  131. { deletes a bindery object and all asociated properties. }
  132.  
  133. {F217/34 [2.15c+]}
  134. Function RenameBinderyObject( objName,NewObjName :string; objType :word ):boolean;
  135. { This function allows the (supervisor-equivalent) user to rename an object,
  136.   given its' type and old name.                                              }
  137.  
  138. {F217/35 [2.15c+] }
  139. Function GetBinderyObjectID( objName:String; objType:word;
  140.                              Var objID:Longint       ):boolean;
  141. { returns the object ID of an object, given its type and name.       }
  142.  
  143. {F217/36 [2.15c+] }
  144. Function GetBinderyObjectName( object_Id:LongInt;
  145.                                Var objName:String; Var objType:word ):boolean;
  146. { returns the type and name of an object, given its four BYTE-id. }
  147.  
  148. {F217/37 [2.15c+]}
  149. Function ScanBinderyObject( SearchObjName: String;
  150.                             SearchObjType: Word;
  151.               {i/o:}    Var lastObjSeen  : Longint;
  152.               {out:}    Var RepName      : String;
  153.                         Var RepType      : Word;
  154.                         Var RepId        : LongInt;
  155.                         Var RepFlag      : Byte;
  156.                         Var RepSecurity  : Byte;
  157.                         Var RepHasProperties: Boolean
  158.                           ) :boolean;
  159. { This function scans the bindery and returns complete information about
  160.   one or more bindery object(s). It can be called iteratively. }
  161.  
  162. {F217/38 [2.15c+]}
  163. Function ChangeBinderyObjectSecurity(objName :String; objType :Word;
  164.                                      NewObjSecurity :Byte           ):boolean;
  165. { Changes the security of a Bindery object. }
  166.  
  167. {F217/39 [2.15c+]}
  168. Function CreateProperty( objName:String; objType:Word;
  169.                     propertyName:String; propFlags,propSecurity:Byte ):boolean;
  170. { Creates a property to be associated with a bindery object. }
  171.  
  172. {F217/3A [2.15c+]}
  173. Function DeleteProperty( objName:String; objType:Word;
  174.                          propertyName:String          ):boolean;
  175. { Deletes a property from a bindery object. }
  176.  
  177. {F217/3B [2.15c+] }
  178. Function ChangePropertySecurity( objName:String; objType:Word;
  179.                                 propName:String; newPropSecurity:Byte ):boolean;
  180. { The call can't assign a greater access security level for the property
  181.  than the security level of the caller. }
  182.  
  183. {F217/3C [2.15c+]}
  184. Function ScanProperty( objName:String; objType:Word; searchPropName:String;
  185.             {i/o var:} Var SequenceNumber:LongInt;
  186.             { output:} Var propName:String;
  187.                        Var propFlags:Byte;
  188.                        Var propSecurity:Byte;
  189.                        Var propHasValue:Boolean;
  190.                        Var moreProperties:Boolean  ):boolean;
  191. { return information about one or more properties. }
  192.  
  193. {F217/3D [2.15c+]}
  194. Function ReadPropertyValue( objName:String; objType:Word;
  195.                             propName:String; segmentNumber:Word;
  196.                             Var propValue   : Tproperty;
  197.                             Var moreSegments: Boolean;
  198.                             Var propFlags   : Byte              ):boolean;
  199. { Returns the value of a property associated with a Bindery object.     }
  200.  
  201. {F217/3E [2.15c+]}
  202. Function WritePropertyValue( objName:String; objType:Word;
  203.                    propName:String; segmentNbr: Byte; propValue:Tproperty;
  204.                    moreSegments:Boolean                   ):boolean;
  205. { Changes the value of a (NON-SET) property associated with a Bindery object. }
  206.  
  207. {F217/3F [2.15c+]}
  208. FUNCTION VerifyBinderyObjectPassword
  209.           ( objName:string; objType:Word; password:string):boolean;
  210. { Verifies the accuracy of a password for a bindery object. (UNencrypted version) }
  211.  
  212. {F217/4A [2.15c+]}
  213. FUNCTION VerifyEncrBinderyObjectPassword
  214.           ( objName:string; objType:Word; password:string):boolean;
  215. { Verifies the accuracy of a password for a bindery object. (ENcrypted version) }
  216.  
  217. {F217/  [2.15c+] }
  218. Function ChangeEncrBinderyObjectPassword(objName:String; objType:Word;
  219.                                          oldPassWord,newPassWord:String ):boolean;
  220. { Changes the password of a bindery object. (UNencrypted version) }
  221.  
  222. {F217/40 [2.0/2.1/3.x] }
  223. Function ChangeBinderyObjectPassword(objName:String; objType:Word;
  224.                                      oldPassWord,newPassWord:String ):boolean;
  225. { Changes the password of a bindery object. (UNencrypted version) }
  226.  
  227. {F217/41 [2.15c+]}
  228. Function AddBinderyObjectToSet(objName:String; objType:Word;propName,
  229.                                memberName:String; memberType:Word ):boolean;
  230. { Adds a bindery object (member) to a property set. }
  231.  
  232. {F217/42 [2.15c+]}
  233. Function DeleteBinderyObjectFromSet(objName:String; objType:Word;propName,
  234.                                     memberName:String; memberType:Word ):boolean;
  235. { Deletes a (member) bindery object from a property set. }
  236.  
  237. {F217/43 [2.15c+]}
  238. Function IsBinderyObjectInSet(objName:String; objType:Word;propName,
  239.                               memberName:String; memberType:Word ):boolean;
  240. { Allows the programmer to check whether a bindery object is a member of a
  241.   set-property. }
  242.  
  243. {F217/44 [2.15c+]}
  244. Function CloseBindery:boolean;
  245. { Closes the bindery files so they can be backed up. (Supervisor only) }
  246.  
  247. {F217/45 [2.15c+]}
  248. Function OpenBindery:boolean;
  249. { This call must be used after the CloseBindery call. No other bindery
  250.   call will work while the bindery is closed.                          }
  251.  
  252. {F217/46 [2.15c+] }
  253. Function getBinderyAccessLevel( {out:} Var SecurityAccesslevel:byte;
  254.                                        Var ObjId:Longint          ): Boolean;
  255. { It returns the user's access level to the bindery.                      }
  256.  
  257. {F217/17 [3.x]}
  258. FUNCTION GetEncryptionKey(VAR key : TencryptionKey): Boolean;
  259. { Used by calls using encrypted passwords to query the target fileserver
  260.   for an encryption key. }
  261.  
  262.  
  263. {F217/49 [2.15c+]}
  264. Function IsStationAManager:boolean;
  265. { Is station a workgroup manager ? }
  266.  
  267.  
  268. {F217/4C [2.15c+]}
  269. Function GetRelationOfBinderyObject(ObjName:string;ObjType:word;
  270.                                relationPropertyName:string;
  271.                          {i/o} Var sequenceNbr:longint;
  272.                          {out} Var NbrOfObjects:word;
  273.                                Var Info:TobjIdArray               ):boolean;
  274.  
  275. {************************** secondary functions: ****************************}
  276.  
  277. Function IsShellLoaded:boolean;
  278. Function IsUserLoggedOn:boolean;
  279. Function ExistsUser(userObjName:string):boolean;
  280. Function GetRealUserName(userObjname:string; Var realname:string):boolean;
  281. Function IsGroupMember(GroupName,UserObjName:String): Boolean;
  282. Function AddUserToGroup(userName,GroupName:String):boolean;
  283. Function DeleteUserFromGroup(userName,GroupName:String):boolean;
  284. Function ExistsFileServer(ServerName:string):Boolean;
  285.  
  286. IMPLEMENTATION{=============================================================}
  287.  
  288.  
  289. {F217/17 [3.x]}
  290. FUNCTION GetEncryptionKey(VAR key : TencryptionKey): Boolean;
  291. Type Treq=RECORD
  292.           len : WORD;
  293.           func: BYTE;
  294.           END;
  295.      TPreq=^Treq;
  296. BEGIN
  297. With TPreq(GlobalReqBuf)^
  298.  do begin
  299.     len := 1;
  300.     func := $17;
  301.     end;
  302. F2SystemCall($17,sizeof(Treq),SizeOf(TencryptionKey),result);
  303. Move(GlobalReplyBuf^,key,SizeOf(key));
  304. GetEncryptionKey:=(Result=0);
  305. END;
  306.  
  307.  
  308. {F217/3F [2.15c+]}
  309. FUNCTION VerifyBinderyObjectPassword
  310.           ( objName:string;objType:Word; password : string):boolean;
  311. { Verifies the accuracy of a password for a bindery object. }
  312. { Passwords need to be converted to upper case, NULL if there is no password. }
  313. Type  TReq=record
  314.            buffer_length : Word;
  315.            subfunction   : byte;
  316.            obj_type      : word; { hi-lo }
  317.            _ObjectName   : string[48];
  318.            _PassWord     : string[127];
  319.            end;
  320.       TPreq=^Treq;
  321. begin
  322. With TPreq(GlobalReqBuf)^
  323. do begin
  324.    buffer_length := SizeOf(Treq)-2;
  325.    subfunction :=$3F;
  326.    obj_type:=swap(objType); { force hi-lo }
  327.    UpString(objName);
  328.    UpString(password);
  329.    PStrCopy(_ObjectName,objName,48); _ObjectName[48]:=#0; UpString(_ObjectName);
  330.    PStrCopy(_PassWord,password,127); Upstring(_PassWord);
  331.   end;
  332. F2SystemCall($17,sizeof(Treq),0,result);
  333. VerifyBinderyObjectPassword:=(result=0);
  334. { possible resultcodes:
  335. $00    0      verification of object_name/password combination
  336. $96  150      Sever out of memory
  337. $C5  197      account disabled due to intrusion lockout
  338. $D6  214      unencrypted password calls not allowed on this v3+ server
  339. $F0  240      Wildcard not allowed
  340. $FB  251      no such property
  341. $FC  252      no such object_name on this server
  342. $FE  254      Server Bindery Locked
  343. $FF  255      Bindery failure (No such object or bad password)        }
  344. end;
  345.  
  346.  
  347. {F217/4A [3.x]}
  348. FUNCTION VerifyEncrBinderyObjectPassword(ObjName: String; ObjType: Word; PassWord: String): Boolean;
  349.  
  350.    FUNCTION VerifyEncrypted(ObjName : String; ObjType : Word; VAR key : TencryptionKey): Boolean;
  351.    Type TReq=RECORD
  352.              BufLen  : Word;
  353.              _func   : Byte;
  354.              _key    : TencryptionKey;
  355.              _ObjType: Word;
  356.              _ObjName: String[48];
  357.              End;
  358.         TPreq=^Treq;
  359.    Begin
  360.    With TPreq(GlobalReqBuf)^
  361.     do Begin
  362.        _func := $4A;
  363.        _key  := key;
  364.        _ObjType := Swap(objType);
  365.        PstrCopy(_ObjName,ObjName,48); UpString(_ObjName);
  366.        if ObjName[0]<#48
  367.         then _objName[0]:=objName[0]
  368.         else _objname[0]:=#48;
  369.        BufLen:=ord(_ObjName[0])+12;
  370.        End;
  371.    F2SystemCall($17,sizeof(Treq),0,result);
  372.    VerifyEncrypted:=(result=0);
  373.    End;
  374.  
  375. VAR
  376.   key : TencryptionKey;
  377.   ObjId:LongInt;
  378.   _pw:string;
  379.  
  380. Begin
  381. UpString(password);
  382. _pw:=password;
  383. if _pw[0]>#127 Then _pw[0]:=#127;
  384.  
  385. IF GetEncryptionKey(key)
  386.  Then Begin
  387.  
  388.       IF GetBinderyObjectId(objName,objType,ObjId)
  389.        Then Begin
  390.             EncryptPassword(objId,_pw,key);
  391.             VerifyEncrypted(ObjName, ObjType, key);
  392.             End;
  393.       End
  394.  Else VerifyBinderyObjectPassword(ObjName, ObjType, Password);
  395.  
  396. VerifyEncrBinderyObjectPassword := (result=0);
  397. End;
  398.  
  399.  
  400. {F217/37 [2.15c+]}
  401. Function ScanBinderyObject( SearchObjName: String;
  402.                             SearchObjType: Word;
  403.               {i/o:}    Var lastObjSeen  : Longint;
  404.               {out:}    Var RepName      : String;
  405.                         Var RepType      : Word;
  406.                         Var RepId        : LongInt;
  407.                         Var RepFlag      : Byte;
  408.                         Var RepSecurity  : Byte;
  409.                         Var RepHasProperties: Boolean
  410.                           ) :boolean;
  411. { This function scans the bindery and returns complete information about
  412.   a bindery object. }
  413. Type TReq = record
  414.           length          : word;
  415.           subfunction     : byte;
  416.           last_obj_id     : longint; {hi-lo}
  417.           search_obj_type : word;    {hi-lo}
  418.           search_obj_name : string[48];
  419.           end;
  420.     TRep= record
  421.           object_id   : longint; {hi-lo}
  422.           object_type : word;    {hi-lo}
  423.           object_name : array [1..48] of byte;
  424.           object_flag : byte;
  425.           security    : byte;
  426.           properties  : byte;
  427.           end;
  428.     TPreq=^Treq;
  429.     TPrep=^Trep;
  430.  
  431. Var TempStr:string;
  432.     count : integer;
  433. begin
  434. with TPreq(GlobalReqBuf)^
  435. do begin
  436.    length := SizeOf(Treq)-2;
  437.    subfunction := $37;
  438.    last_obj_id := Lswap(lastObjseen);  { force hi-lo }
  439.    search_obj_type:= swap(Word(SearchObjType)); { force hi-lo }
  440.    PstrCopy(Search_obj_name,SearchObjName,48); Search_obj_Name[48]:=#0; UpString(Search_obj_name);
  441.    end;
  442. F2SystemCall($17,sizeOf(Treq),sizeOf(Trep),result);
  443. With TPrep(GlobalReplyBuf)^
  444. do begin
  445.    repFlag := object_flag;
  446.    repHasProperties := (properties>0);
  447.    repSecurity := security;
  448.    repType := swap(object_type); { force lo-hi }
  449.    repId := Lswap(object_id);    { force lo-hi }
  450.    lastObjSeen := repId;
  451.    ZStrCopy(repName,Object_Name,48);
  452.    end;
  453. scanBinderyObject:=(result=0);
  454. { Possible Resultcodes:
  455.   96h server out of memory; EFh Invalid Name; FCh No Such Object;
  456.   FEh Server Bindery Locked; FFh Bindery failure                  }
  457. end;
  458.  
  459.  
  460. {F217/3D [2.15c+]}
  461. Function ReadPropertyValue( objName:String; objType:Word;
  462.                             propName:String; segmentNumber:Word;
  463.                             Var propValue   : Tproperty;
  464.                             Var moreSegments: Boolean;
  465.                             Var propFlags   : Byte              ):boolean;
  466. { Returns the value of a property associated with a Bindery object.     }
  467. Type Treq=record
  468.           len         : word;
  469.           subfunction : byte;
  470.           _objType    : word;  { hi-lo }
  471.           _ObjName    : string[48];
  472.           _segNbr     : byte;
  473.           _propName   : string[15];
  474.           end;
  475.     Trep = record
  476.            _propValue : Tproperty; {array [1..128] of byte}
  477.            _moreSegments : byte;
  478.            _propFlags : byte;
  479.            end;
  480.     TPreq=^Treq;
  481.     TPrep=^Trep;
  482. BEGIN
  483.  With TPreq(GlobalReqBuf)^
  484.  do begin
  485.     len:=SizeOf(Treq)-2;
  486.     subfunction  := $3d;
  487.     _objType:=swap(objType); { force hi-lo }
  488.     _segNbr:=segmentNumber;
  489.     PStrCopy(_ObjName,objName,48); _ObjName[48]:=#0; UpString(_ObjName);
  490.     PStrCopy(_PropName,propName,15); UpString(_propName);
  491.     end;
  492. F2SystemCall($17,sizeof(Treq),sizeof(Trep),result);
  493. if result=0
  494.  then with TPrep(GlobalreplyBuf)^
  495.       do begin
  496.          propValue:=_propValue;
  497.          moreSegments:=(_moreSegments>0);
  498.          propFlags:=_propFlags;
  499.          end;
  500. ReadPropertyValue:=(result=0);
  501. { 96 server out of memory; EC no such segment; F0 wilcard not allowed;
  502.   f1 invalid bindery security; f9 no property read privileges;
  503.   fb no such property; fc no such object; FE Server Bindery Locked;
  504.   FF Bindery Failure.                                                 }
  505. end;
  506.  
  507.  
  508. {F217/36 [2.15c+] }
  509. Function GetBinderyObjectName( object_Id:LongInt;
  510.                                Var objName:String; Var objType:word ):boolean;
  511. { returns the type and name of an object, given its four BYTE-id. }
  512. Type TReq =record
  513.          len:word;
  514.          subF:byte;
  515.          _objId:LongInt;  { hi-lo }
  516.          end;
  517.      Trep=record
  518.          _objId:LongInt;  { hi-lo }
  519.          _objType:word;   { hi-lo }
  520.          _objName:array[1..48] of Byte;
  521.          end;
  522.      TPreq=^Treq;
  523.      TPrep=^Trep;
  524. BEGIN
  525. WITH TPreq(GlobalReqBuf)^
  526. do begin
  527.    len :=SizeOf(TReq)-2;
  528.    SubF:=$36;
  529.    _objId:=Lswap(object_Id); { force hi-lo }
  530.    end;
  531. F2SystemCall($17,sizeOf(Treq),sizeOf(Trep),result);
  532. IF result=0
  533.  then with TPrep(GlobalReplyBuf)^
  534.       do begin
  535.          ZstrCopy(objName,_objName,48);
  536.          objType:=swap(_objType); { force lo-hi }
  537.          end;
  538. GetBinderyObjectName:=(result=0);
  539. end;
  540.  
  541.  
  542. {F217/35 [2.15c+] }
  543. Function GetBinderyObjectID( objName:String; objType:word;
  544.                              Var objID:Longint       ):boolean;
  545. { returns the object ID of an object, given its type and name.       }
  546. Type Treq=record
  547.          len:word;
  548.          subF:Byte;
  549.          _objType:word;   { hi-lo }
  550.          _objName:string[48];
  551.          end;
  552.      TRep=record
  553.          _objId:LongInt;  { hi-lo }
  554.          _objType:word;   { hi-lo }
  555.          _objName:array[1..48] of char;
  556.          end;
  557.      TPreq=^Treq;
  558.      TPrep=^Trep;
  559. BEGIN
  560. WITH TPreq(GlobalReqBuf)^
  561. do begin
  562.    len :=SizeOf(TReq)-2;
  563.    SubF:=$35;
  564.    _objType:=swap(objType); { force hi-lo }
  565.    PStrCopy(_objName,objName,48); _objName[48]:=#0;
  566.    UpString(_objName);
  567.    end;
  568. F2SystemCall($17,sizeOf(Treq),sizeOf(Trep),result);
  569. IF result=0
  570.  then with TPrep(GlobalReplyBuf)^
  571.        do objID:=Lswap(_objId); { force lo-hi }
  572. GetBinderyObjectID:=(result=0);
  573. end;
  574.  
  575.  
  576. {F217/46 [2.15c+]}
  577. Function getBinderyAccessLevel(Var SecurityAccessLevel:byte;
  578.                                Var objId:Longint ):boolean;
  579. { It returns the user's access level to the bindery.                      }
  580. { Often used as a quick way of determining the current users' object id   }
  581. { use the BS_xxxx constants to determine the exact rights of the user     }
  582. Type Treq=record
  583.           len      :word;
  584.           subF     :byte;
  585.           end;
  586.      Trep=record
  587.           accLeveL:byte;
  588.           _objId:longInt;
  589.           fill:array[1..20] of byte;
  590.           end;
  591.      TPreq=^Treq;
  592.      TPrep=^Trep;
  593. BEGIN
  594. With TPreq(GlobalReqBuf)^
  595.  do begin
  596.     subF:=$46;
  597.     len:=sizeOf(Treq)-2;
  598.     end;
  599. F2SystemCall($17,sizeOf(Treq),sizeOf(Trep),result);
  600. If result=0
  601.  then with TPrep(GlobalReplyBuf)^
  602.        do begin
  603.           SecurityAccessLevel:=accLevel;
  604.           objId:=Lswap(_objId);
  605.           end;
  606. GetBinderyAccessLevel:=(result=0);
  607. end;
  608.  
  609.  
  610.  
  611. {F217/45 [2.15c+]}
  612. Function OpenBindery:boolean;
  613. { This call must be used after the CloseBindery call. No other bindery
  614.   call will work while the bindery is closed.                          }
  615. Type Treq=record
  616.           len:word;
  617.           subFunc:byte;
  618.           end;
  619.      TPreq=^Treq;
  620. Begin
  621. WITH TPreq(GlobalReqBuf)^
  622. do begin
  623.    len:=1;
  624.    subFunc:=$45;
  625.    end;
  626. F2SystemCall($17,sizeOf(Treq),0,result);
  627. OpenBindery:=(result=0)
  628. end;
  629.  
  630.  
  631. {F217/44 [2.15c+]}
  632. Function CloseBindery:boolean;
  633. { Closes the bindery files so they can be backed up. (Supervisor only) }
  634. Type Treq=record
  635.           len:word;
  636.           subFunc:byte;
  637.           end;
  638.      TPreq=^Treq;
  639. Begin
  640. WITH TPreq(GlobalReqBuf)^
  641. do begin
  642.    len:=SizeOf(Treq)-2;
  643.    subFunc:=$44;
  644.    end;
  645. F2SystemCall($17,sizeOf(Treq),0,result);
  646. CloseBindery:=(result=0)
  647. end;
  648.  
  649.  
  650. {F217/32 [2.15c+] }
  651. Function CreateBinderyObject(objName:string; objType:Word;
  652.                              objFlaG, objSecurity :Byte   ):boolean;
  653. { Creates an object in the bindery.
  654.   objName: name of the new object (47 chars)
  655.   objType: object type number (own type number or OT_xxx constant)
  656.   objFlag: identifies an object as static (0) or dynamic (1)
  657.            (dynamic objects are removed from the bindery when the server goes down)
  658.   objSecurity: high nibble: write privileges needed to modify this object
  659.                low  nibble: read privileges needed to access this object
  660.                (default: $31 Supervisor write/Logged read) }
  661. Type Treq=record
  662.           len          :word;
  663.           subFunc      :byte;
  664.           _objFlag     :Byte;
  665.           _objSecurity :Byte;
  666.           _objType     :word; { hi-lo }
  667.           _objName     :string[48]
  668.           end;
  669.      TPreq=^Treq;
  670. Begin
  671. WITH TPreq(GlobalReqBuf)^
  672. do begin
  673.    len:=SizeOf(Treq)-2;
  674.    subFunc:=$32;
  675.    _objFlag:=objFlag;
  676.    _objSecurity:=objSecurity;
  677.    _objType:=swap(objType); { force hi-lo }
  678.    PStrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
  679.   end;
  680. F2SystemCall($17,sizeof(Treq),0,result);
  681. CreateBinderyObject:=(result=0)
  682. { 96h server out of memory; EEh Object Already Exists; EFh Invalid Name
  683.   F1h invalid Bindery security; F5h no object create privileges
  684.   FEh Server Bindery Locked; FFh Bindery Failure                        }
  685. end;
  686.  
  687.  
  688.  
  689. {F217/33 [2.15c+] }
  690. Function DeleteBinderyObject( objName:String; objType:Word ):boolean;
  691. { deletes a bindery object and all asociated properties. }
  692. Type Treq=record
  693.           len      :word;
  694.           subFunc  :byte;
  695.           _objType :Word; { hi-lo }
  696.           _objName :string[48];
  697.           end;
  698.      TPreq=^Treq;
  699. Begin
  700. WITH TPreq(GlobalreqBuf)^
  701. do begin
  702.    len:=SizeOf(Treq)-2;
  703.    subFunc:=$33;
  704.    _objType:=swap(objType); { force hi-lo }
  705.    PStrCopy(_objName,objName,48); _objName[48]:=#48; UpString(_objName);
  706.    end;
  707. F2SystemCall($17,sizeOf(Treq),0,result);
  708. DeleteBinderyObject:=(result=0)
  709. { 96h Server out of memory; EFh Invalid name; F0h wildcard not allowed;
  710.   F4h No object delete privileges; FCh no such object
  711.   FEh Server Bindery Locked; FFh bindery failure                        }
  712. end;
  713.  
  714.  
  715. {F217/34 [2.15c+]}
  716. Function RenameBinderyObject( objName,NewObjName :string; objType :word ):boolean;
  717. { This function allows the (supervisor-equivalent) user to rename an object,
  718.   given its' type and old name.                                              }
  719. Type Treq=record
  720.           len         :word;
  721.           subFunc     :byte;
  722.           _objType    :word; { hi-lo }
  723.           _objName    :string[48];
  724.           _NewObjName :string[48];
  725.           end;
  726.     TPreq=^Treq;
  727. Begin
  728. WITH TPreq(GlobalReqBuf)^
  729. do begin
  730.    len:=SizeOf(Treq)-2;
  731.    subFunc:=$34;
  732.    _objType:=swap(objType); { force hi-lo }
  733.    PstrCopy(_objName,objName,48); _objName[48]:=#0; Upstring(_objName);
  734.    PstrCopy(_NewObjName,NewObjName,48); _NewObjName[48]:=#0; UpString(_NewObjName);
  735.    end;
  736. F2SystemCall($17,sizeOf(Treq),0,result);
  737. RenameBinderyObject:=(result=0)
  738. { 96h Server out of memory; EFh Invalid name; F0h wildcard not allowed;
  739.   F3h No object rename privileges; FCh no such object
  740.   FEh Server Bindery Locked; FFh bindery failure                        }
  741. end;
  742.  
  743.  
  744.  
  745. {F217/43 [2.15c+]}
  746. Function IsBinderyObjectInSet(objName:String; objType:Word;
  747.                  propName, memberName:String; memberType:Word ):boolean;
  748. { Allows the programmer to check whether a bindery object is a member of a
  749.   set-property. Objectname( of Objecttype) is the object to be searched for,
  750.   PropName (attached to the object with name memberName (of memberType))
  751.   is the property containing the set to be searched.
  752.   User must have read rights to the object and the property.
  753.   Ex: ('SUPERVISOR',OT_USER,'GROUP_MEMBERS','EVERYONE',OT_USER_GROUP)       }
  754. Type Treq=record
  755.           len         :word;
  756.           subFunc     :byte;
  757.           _objType    :Word;       { hi-lo   }
  758.           _objName    :String[48]; { [48]=#0 }
  759.           _propName   :String[15];
  760.           _memObjType :Word;       { hi-lo   }
  761.           _memName    :String[48]; { [48]=#0 }
  762.           end;
  763.      TPreq=^Treq;
  764. Begin
  765. WITH TPreq(GlobalReqBuf)^
  766. do begin
  767.    len:=SizeOf(Treq)-2;
  768.    subFunc:=$43;
  769.    _objType:=swap(objType); { force hi-lo }
  770.    PstrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
  771.    PstrCopy(_propName,propName,15); UpString(_propName);
  772.    _memObjType:=swap(memberType); { force hi-lo }
  773.    PStrCopy(_memName,memberName,48); _memName[48]:=#0; UpString(_memName);
  774.    end;
  775. F2SystemCall($17,sizeOf(Treq),0,result);
  776. IsBinderyObjectInSet:=(result=0)
  777. { 96h Server out of memory; EA No Such member; EB Not Group Property
  778.   F0h wildcard not allowed; F9 No Property read privileges;
  779.   FCh no such object; FEh Server Bindery Locked; FFh bindery failure        }
  780. end;
  781.  
  782.  
  783.  
  784. {F217/41 [2.15c+]}
  785. Function AddBinderyObjectToSet(objName:String; objType:Word;
  786.                   propName, memberName:String; memberType:Word ):boolean;
  787. { Adds a bindery object to a property set.
  788.   user must have write access to the set property.                        }
  789. Type Treq=record
  790.           len         :word;
  791.           subFunc     :byte;
  792.           _objType    :Word;       { hi-lo   }
  793.           _objName    :String[48]; { [48]=#0 }
  794.           _propName   :String[15];
  795.           _memObjType :Word;       { hi-lo   }
  796.           _memName    :String[48]; { [48]=#0 }
  797.           end;
  798.      TPreq=^Treq;
  799. Begin
  800. WITH TPreq(GlobalReqBuf)^
  801. do begin
  802.    len:=SizeOf(Treq)-2;
  803.    subFunc:=$41;
  804.    _objType:=swap(objType); { force hi-lo }
  805.    PstrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
  806.    PstrCopy(_propName,propName,15); UpString(_propName);
  807.    _memObjType:=swap(memberType); { force hi-lo }
  808.    PStrCopy(_memName,memberName,48); _memName[48]:=#0; UpString(_memName);
  809.    end;
  810. F2SystemCall($17,sizeOf(Treq),0,result);
  811. AddBinderyObjectToSet:=(result=0)
  812. { 96h Server out of memory; E9 Member already Exists; EB Not Group Property
  813.   F0h wildcard not allowed; F8 No Property write privileges;
  814.   FCh no such object; FEh Server Bindery Locked; FFh bindery failure        }
  815. end;
  816.  
  817.  
  818. {F217/42 [2.0/2.1/3.x]}
  819. Function DeleteBinderyObjectFromSet(objName:String; objType:Word;
  820.                        propName, memberName:String; memberType:Word ):boolean;
  821. { Deltes a bindery object from a property set.
  822.   user must have write access to the set property.                        }
  823. Type Treq=record
  824.           len         :word;
  825.           subFunc     :byte;
  826.           _objType    :Word;       { hi-lo   }
  827.           _objName    :String[48]; { [48]=#0 }
  828.           _propName   :String[15];
  829.           _memObjType :Word;       { hi-lo   }
  830.           _memName    :String[48]; { [48]=#0 }
  831.           end;
  832.      TPreq=^Treq;
  833. Begin
  834. WITH TPreq(GlobalReqBuf)^
  835. do begin
  836.    len:=SizeOf(Treq)-2;
  837.    subFunc:=$42;
  838.    _objType:=swap(objType); { force hi-lo }
  839.    PstrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
  840.    PstrCopy(_propName,propName,15); UpString(_propName);
  841.    _memObjType:=swap(memberType); { force hi-lo }
  842.    PStrCopy(_memName,memberName,48); _memName[48]:=#0; UpString(_memName);
  843.    end;
  844. F2SystemCall($17,sizeOf(Treq),0,result);
  845. DeleteBinderyObjectFromSet:=(result=0)
  846. { 96h Server out of memory; EA No Such Member; EB Not Group Property
  847.   F0h wildcard not allowed; F8 No Property write privileges; FB No Such property;
  848.   FCh no such object; FEh Server Bindery Locked; FFh bindery failure        }
  849. end;
  850.  
  851.  
  852. {F217/38 [2.15c+]}
  853. Function ChangeBinderyObjectSecurity(objName :String; objType :Word;
  854.                                      NewObjSecurity :Byte           ):boolean;
  855. { Changes the security of a Bindery object. This call is made successfully,
  856.   if the user is supervisor equivalent and the current security is unequal to
  857.   NetWare Read/ NetWare Write.                                              }
  858. Type Treq=record
  859.           len      :word;
  860.           subFunc  :byte;
  861.           _NobjSec :Byte;
  862.           _objType :Word; { hi-lo }
  863.           _objName :String[48]; { [48]=#0 }
  864.           end;
  865.      TPreq=^Treq;
  866. Begin
  867. WITH TPreq(GlobalReqBuf)^
  868. do begin
  869.    len:=SizeOf(Treq)-2;
  870.    subFunc:=$38;
  871.    _NobjSec:=NewObjSecurity;
  872.    _objType:=swap(objType); { force hi-lo }
  873.    PstrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
  874.    end;
  875. F2SystemCall($17,sizeOf(Treq),0,result);
  876. ChangeBinderyObjectSecurity:=(result=0)
  877. { Completion Codes:
  878.   96 Server out of memory; F0 Wildcard Not Allowed; F1 Invalid Bindery Security;
  879.   FC No Such Object; FE Server Bindery Locked; FF Bindery Failure.           }
  880. end;
  881.  
  882.  
  883.  
  884.  
  885. {F217/4B [3.x]}
  886. FUNCTION ChangeEncrBinderyObjectPassword(ObjName: String; ObjType: Word;
  887. {#d}                      oldPassWord,newPassword: String): Boolean;
  888. { Changes the password of a bindery object.
  889.   Old Password can be NULL. To log into a file server, an object must have a
  890.   PASSWORD property. User must have read and write access to the bindery object. }
  891.    FUNCTION ChangeEncrypted(ObjName : String; ObjType : Word;
  892.                             oldEncrPW:TencryptionKey;
  893.                             Var newPWdif:TencrPWdifference;
  894.                             PWdifCheckSum:byte
  895.                            ):boolean;
  896.    Type Treq=RECORD
  897.              BufLen  : Word;
  898.              _func   : Byte;
  899.              _oldPW  : TencryptionKey;
  900.              _ObjType: Word;
  901.              _ObjNameLen : byte;
  902.              _Various: array [1..48+1+16] of byte;  { ObjName, difCheksum, PWdif }
  903.              End;
  904.         TPreq=^Treq;
  905.    Begin
  906.    With TPreq(GlobalreqBuf)^
  907.     do Begin
  908.        _func := $4B;
  909.        _oldPW:=oldEncrPW;
  910.        _ObjType := Swap(objType);
  911.        if objName[0]>#48
  912.         then objName[0]:=#48;
  913.        move (objName[0],_objNameLen,ord(objName[0])+1);
  914.        _Various[_objNamelen+1]:=PWdifCheckSum;
  915.        move(newPWdif,_Various[_objNamelen+2],16);
  916.        BufLen:=29+_objNameLen;
  917.        F2SystemCall($17,buflen+2,0,result);
  918.        end;
  919.    ChangeEncrypted:=(result=0);
  920.    End;
  921.  
  922. VAR
  923.   key : TencryptionKey;
  924.   ObjId:LongInt;
  925.   PWdif:TencrPWdifference;
  926.   PWdifChecksum:byte;
  927.  
  928. Begin
  929. UpString(oldPassword);
  930. if oldPassword[0]>#127
  931.  Then oldPassword[0]:=#127;
  932. UpString(newPassword);
  933. if newPassword[0]>#127
  934.  Then newPassword[0]:=#127;
  935. UpString(ObjName);
  936.  
  937. IF GetEncryptionKey(key)
  938.  Then Begin
  939.       IF GetBinderyObjectId(objName,objType,ObjId)
  940.        Then Begin
  941.             EncryptPasswordDifference(objId,
  942.                                       OldPassword,NewPassword,
  943.                                       key,          { i/o, out: EncrOldPW }
  944.                                       PWdif,        { out, 16 bytes }
  945.                                       PWdifChecksum { out, 1 byte }
  946.                                       );
  947.             ChangeEncrypted(ObjName, ObjType, key, PWdif, PWdifChecksum);
  948.             End;
  949.       End
  950.  Else ChangeBinderyObjectPassword(ObjName, ObjType, OldPassword, NewPassword);
  951.  
  952. ChangeEncrBinderyObjectPassword:= (result=0);
  953. { Completion Codes:
  954.   96 Server Out Of Memory; F0 Wildcard Not Allowed; FB No Such Property;
  955.   FC No Such Object; FE Server Bindery Locked; FF No Such Object *OR*
  956.   No Password Associated With Object *OR* Old Password Invalid.           }
  957. End;
  958.  
  959.  
  960. {F217/40 [2.0/2.1/3.x] }
  961. Function ChangeBinderyObjectPassword(objName:String; objType:Word;
  962.                                   oldPassWord,newPassWord:String ):boolean;
  963. { Changes the password of a bindery object.
  964.   Allow unencrypted passwords must be ON!
  965.   Old Password can be NULL. To log into a file server, an object must have a
  966.   PASSWORD property. User must have read and write access to the bindery object. }
  967. Type Treq=record
  968.           len      :word;
  969.           subFunc  :byte;
  970.           _objType :Word;        { hi-lo }
  971.           _objName :String[48];  { [48]=#0 }
  972.           _oldPW   :String[128]; { wow! a password of 128 chars! }
  973.           _newPW   :String[128];
  974.           end;
  975.     TPreq=^Treq;
  976. Begin
  977. WITH TPreq(GlobalReqBuf)^
  978. do begin
  979.    len:=SizeOf(Treq)-2;
  980.    subFunc:=$40;
  981.    _objType:=swap(objType); { force hi-lo }
  982.    PStrCopy(_objName,objName,48); _ObjName[48]:=#0; UpString(_objName);
  983.    PStrCopy(_oldPW,oldPassWord,128); UpString(_oldPW);
  984.    PStrCopy(_newPW,newPassWord,128); UpString(_newPW);
  985.    end;
  986. F2SystemCall($17,sizeOf(Treq),0,result);
  987. ChangeBinderyObjectPassword:=(result=0)
  988. { Completion Codes:
  989.   96 Server Out Of Memory; F0 Wildcard Not Allowed; FB No Such Property;
  990.   FC No Such Object; FE Server Bindery Locked; FF No Such Object *OR*
  991.   No Password Associated With Object *OR* Old Password Invalid.           }
  992. end;
  993.  
  994.  
  995.  
  996.  
  997. {F217/39 [2.15c+]}
  998. Function CreateProperty( objName:String; objType:Word;
  999.                     propertyName:String; propFlags,propSecurity:Byte ):boolean;
  1000. { Creates a property to be associated with a bindery object.
  1001.   property flags tell whether a property is dynamic or static and whether
  1002.   the property is defined as static or dynamic.                            }
  1003. Type Treq=record
  1004.           len       :word;
  1005.           subFunc   :byte;
  1006.           _objType  :Word;       { hi-lo }
  1007.           _objName  :String[48]; { [48]=#0 }
  1008.           _propFlags:Byte;
  1009.           _propSec  :Byte;
  1010.           _propName :String[15];
  1011.           end;
  1012.      TPreq=^Treq;
  1013. Begin
  1014. WITH TPreq(GlobalReqBuf)^
  1015. do begin
  1016.    len:=SizeOf(Treq)-2;
  1017.    subFunc:=$39;
  1018.    _objType:=swap(objType); { force hi-lo }
  1019.    PStrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
  1020.    _propFlags:=propFlags;
  1021.    _propSec:=propSecurity;
  1022.    PStrCopy(_propName,propertyName,15); UpString(_propName);
  1023.    end;
  1024. F2SystemCall($17,sizeof(Treq),0,result);
  1025. CreateProperty:=(result=0)
  1026. { Completion Codes:
  1027.   96 Server Out Of Memory; ED Property already exists; EF Invalid Name;
  1028.   F0 Wildcard Not Allowed; F1 Invalid Bindery Security; F7 No Property Create Privileges;
  1029.   FC No Such Object; FE Server Bindery Locked; FF Bindery Failure           }
  1030. end;
  1031.  
  1032.  
  1033. {F217/3A [2.15c+]}
  1034. Function DeleteProperty( objName:String; objType:Word;
  1035.                          propertyName:String          ):boolean;
  1036. { Deletes a property from a bindery object.
  1037.   The property field may contain wildcards.                                 }
  1038. Type Treq=record
  1039.           len       :word;
  1040.           subFunc   :byte;
  1041.           _objType  :Word;       { hi-lo }
  1042.           _objName  :String[48]; { [48]=#0 }
  1043.           _propName :String[15];
  1044.           end;
  1045.      TPreq=^Treq;
  1046. Begin
  1047. WITH TPreq(GlobalReqBuf)^
  1048. do begin
  1049.    len:=SizeOf(Treq)-2;
  1050.    subFunc:=$3A;
  1051.    _objType:=swap(objType); { force hi-lo }
  1052.    PStrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
  1053.    PStrCopy(_propName,propertyName,15); UpString(_propName);
  1054.    end;
  1055. F2SystemCall($17,sizeOf(Treq),0,result);
  1056. DeleteProperty:=(result=0)
  1057. { Completion Codes:
  1058.   96 Server Out Of Memory; F0 Wildcard Not Allowed; F1 Invalid Bindery Security;
  1059.   F6 No property delete privileges; FB No Such property;
  1060.   FC No Such Object; FE Server Bindery Locked; FF Bindery Failure           }
  1061. end;
  1062.  
  1063.  
  1064. {F217/3C [2.15c+]}
  1065. Function ScanProperty( objName:String; objType:Word; searchPropName:String;
  1066.             {i/o var:} Var SequenceNumber:LongInt;
  1067.             { output:} Var propName:String;
  1068.                        Var propFlags:Byte;
  1069.                        Var propSecurity:Byte;
  1070.                        Var propHasValue:Boolean;
  1071.                        Var moreProperties:Boolean  ):boolean;
  1072. { Sequence number should be -1 the first time this call is made.
  1073.   The call can be reiterated (by supplying the returned Seq.#) until
  1074.   moreProperties=FALSE or nwBindry.Result=NO_SUCH_PROPERTY.
  1075.   searchPropName may contain wildcards;
  1076.   If propHasValue=TRUE, the value can be read by calling ReadPropertyValue;
  1077.   moreProperties=TRUE if more properties exist for this object.            }
  1078. Type Treq=record
  1079.           len       :word;
  1080.           subFunc   :byte;
  1081.           _objType  :Word;    {hi-lo}
  1082.           _objName  :String[48];
  1083.           _SeqNbr   :LongInt; {hi-lo}
  1084.           _propName :String[15];
  1085.           end;
  1086.      Trep=record
  1087.           _propName :array[1..16] of Byte;
  1088.           _propFlags:Byte;
  1089.           _propSec  :Byte;
  1090.           _SeqNbr   :Longint; {hi-lo}
  1091.           _propHasValue:Byte;
  1092.           _moreProp :Byte;
  1093.           end;
  1094.      TPreq=^Treq;
  1095.      TPrep=^Trep;
  1096. Begin
  1097. WITH TPreq(GlobalReqBuf)^
  1098. do begin
  1099.    len:=SizeOf(Treq)-2;
  1100.    subFunc:=$3C;
  1101.    _objType:=swap(objType); { force hi-lo }
  1102.    PStrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
  1103.    _SeqNbr:=Lswap(SequenceNumber); { force hi-lo }
  1104.    PstrCopy(_propName,searchPropName,15); UpString(_propName);
  1105.    end;
  1106. F2SystemCall($17,sizeof(Treq),sizeof(Trep),result);
  1107. With TPrep(GlobalReplyBuf)^
  1108. do begin
  1109.    SequenceNumber:=Lswap(_SeqNbr); { force lo-hi }
  1110.    ZStrCopy(propName,_propName,15);
  1111.    propFlags:=_propFlags;
  1112.    propSecurity:=_propSec;
  1113.    propHasValue:=(_propHasValue>0);
  1114.    moreProperties:=(_moreProp>0);
  1115.    end;
  1116. ScanProperty:=(result=0)
  1117. { Completion Codes:
  1118.   96 Server Out Of Memory; F1 Invalid Bindery Security; FB No Such property;
  1119.   FC No Such Object; FE Server Bindery Locked; FF Bindery Failure           }
  1120. end;
  1121.  
  1122.  
  1123. {F217/3E [2.15c+]}
  1124. Function WritePropertyValue( objName:String; objType:Word;
  1125.                    propName:String; segmentNbr: Byte; propValue:Tproperty;
  1126.                    moreSegments:Boolean                   ):boolean;
  1127. { Changes the value of a (NON-SET) property associated with a Bindery object.}
  1128. Type Treq=record
  1129.           len         :word;
  1130.           subFunc     :byte;
  1131.           _objType    :Word; { hi-lo }
  1132.           _objName    :String[48];
  1133.           _segNbr     :Byte;
  1134.           _EraseRemainingSeg:Byte; { FF=true 00=false }
  1135.           _propName   :String[15];
  1136.           _propValSeg :Tproperty;
  1137.           end;
  1138.     TPreq=^Treq;
  1139. Begin
  1140. WITH TPreq(GlobalReqBuf)^
  1141. do begin
  1142.    len:=SizeOf(Treq)-2;
  1143.    subFunc:=$3E;
  1144.    _objType:=swap(objType); { force hi-lo }
  1145.    PStrCopy(_objName,objName,48); _objName[48]:=#0; UpString(_objName);
  1146.    _segNbr:=segmentNbr;
  1147.    if moreSegments
  1148.      then _EraseRemainingSeg:=$00
  1149.      else _EraseRemainingSeg:=$FF;
  1150.    PstrCopy(_propName,propName,15); UpString(_propName);
  1151.    _propValSeg:=propValue;
  1152.    end;
  1153. F2SystemCall($17,sizeOf(Treq),0,result);
  1154. WritePropertyValue:=(result=0)
  1155. { Completion Codes:
  1156.   96 Server Out Of Memory; E8 Not Item Property; EC no such segment;
  1157.   F0 Wildcard Not Allowed; F1 Invalid Bindery Security;
  1158.   F8 No property write privileges; FB No Such property;
  1159.   FC No Such Object; FE Server Bindery Locked; FF Bindery Failure           }
  1160. end;
  1161.  
  1162. {F217/3B [2.15c+] }
  1163. Function ChangePropertySecurity( objName:String; objType:Word;
  1164.                                 propName:String; newPropSecurity:Byte ):boolean;
  1165. { The user must have read and write access to the property to make this call.
  1166.   The call can't assign a greater security level than the security level of
  1167.   the caller.                                                               }
  1168. Type Treq=record
  1169.           len:word;
  1170.           subFunc:byte;
  1171.           _objType:Word; { hi-lo }
  1172.           _objName:String[48];
  1173.           _NewPropSec:Byte;
  1174.           _PropName:String[15];
  1175.           end;
  1176.     TPreq=^Treq;
  1177. Begin
  1178. WITH TPreq(GlobalReqBuf)^
  1179. do begin
  1180.    len:=SizeOf(Treq)-2;
  1181.    subFunc:=$3B;
  1182.    _objType:=swap(objType); { force hi-lo }
  1183.    PstrCopy(_objName,objName,48); _objName[48]:=#0; Upstring(_objName);
  1184.    _NewPropSec:=NewPropSecurity;
  1185.    PstrCopy(_propName,propName,15); Upstring(_propName);
  1186.    end;
  1187. F2SystemCall($17,sizeOf(Treq),0,result);
  1188. ChangePropertySecurity:=(result=0)
  1189. { Completion Codes:
  1190.   96 Server Out Of Memory; F0 Wildcard Not Allowed; F1 Invalid Bindery Security;
  1191.   FB No Such property;  FC No Such Object; FE Server Bindery Locked;
  1192.   FF Bindery Failure                                                         }
  1193. end;
  1194.  
  1195. {F217/49 [3.0+]}
  1196. Function IsStationAManager:boolean;
  1197. { Fast way to detremine if: object ID of caller included in the MANAGERS
  1198.   set property attached to the SUPERVISOR object. }
  1199. Type Treq=record
  1200.           len:word;
  1201.           subFunc:byte;
  1202.           end;
  1203.      Trep=record
  1204.           unknown:byte;
  1205.           end;
  1206.      TPreq=^Treq;
  1207.      TPrep=^Trep;
  1208. Begin
  1209. WITH TPreq(GlobalReqBuf)^
  1210.  do begin
  1211.     len:=SizeOf(Treq)-2;
  1212.     subFunc:=$49;
  1213.     end;
  1214. F2SystemCall($17,SizeOf(Treq),Sizeof(Trep),result);
  1215. {With TPrep(GlobalReplyBuf)^
  1216.   do begin
  1217.  
  1218.      end; }
  1219. IsStationAManager:=(result=0)
  1220. { Completion codes:
  1221.   00 Successful (WS is a manager);
  1222.   FF Not a manager }
  1223. end;
  1224.  
  1225. {F217/4C [3.0+]}
  1226. Function GetRelationOfBinderyObject(ObjName:string;ObjType:word;
  1227.                                relationPropertyName:string;
  1228.                          {i/o} Var sequenceNbr:longint;
  1229.                          {out} Var NbrOfObjects:word;
  1230.                                Var Info:TobjIdArray         ):boolean;
  1231. { OBJ_SUPERVISORS  GROUPS_I'M_IN  SECURITY_EQUALS }
  1232. Type Treq=record
  1233.           len            :word;
  1234.           subFunc        :byte;
  1235.           _SeqObjId      :Longint; {hi-lo}
  1236.           _ObjType       :word;  {hi-lo}
  1237.           _ObjAndPropName:string;
  1238.           end;
  1239.      Trep=record
  1240.           _NbrOfObj:Word;
  1241.           _Info    :TobjIdArray;
  1242.           end;
  1243.      TPreq=^Treq;
  1244.      TPrep=^Trep;
  1245. Var t:byte;
  1246. Begin
  1247. WITH TPreq(GlobalReqBuf)^
  1248.  do begin
  1249.     subFunc:=$4C;
  1250.     _SeqObjId:=Lswap(SequenceNbr);
  1251.     _ObjType:=swap(ObjType);
  1252.     Upstring(ObjName);UpString(RelationPropertyName);
  1253.     _ObjAndPropName:=ObjName;
  1254.     move(RelationPropertyName[0],
  1255.          _ObjAndPropName[ord(ObjName[0])+1],
  1256.          ord(RelationPropertyName[0])+1);
  1257.     len:=9+ord(ObjName[0])+ord(RelationPropertyName[0]);
  1258.     F2SystemCall($17,len+2,Sizeof(Trep),result);
  1259.     end;
  1260. With TPrep(GlobalReplyBuf)^
  1261.  do begin
  1262.     NbrOfObjects:=swap(_NbrOfObj);
  1263.     for t:= 1 to NbrOfObjects
  1264.      do Info[t]:=Lswap(_Info[t]);
  1265.     if NbrOfObjects=$20
  1266.      then SequenceNbr:=Info[$20]
  1267.      else SequenceNbr:=-1;
  1268.     end;
  1269. if result<>0 then SequenceNbr:=-1;
  1270. GetRelationOfBinderyObject:=(result=0)
  1271. end;
  1272.  
  1273.  
  1274.  
  1275. {=======SECONDARY FUNCTIONS===================================================}
  1276.  
  1277.  
  1278.  
  1279. Function IsShellLoaded:boolean;
  1280. Var mask:byte;
  1281.     id:LongInt;
  1282. begin
  1283. {$IFNDEF MSDOS}
  1284. FillChar(nwintr.GlobalReplyBuf^,Sizeof(nwintr.TintrBuffer),#$0);
  1285. { Only needed in protected mode, otherwise an invalid value is reported.
  1286.   Doesn't harm a bit if you use it in other modes, though. }
  1287. {$ENDIF}
  1288. IsShellLoaded:=(nwBindry.getBinderyAccessLevel(mask,id) and (id<>0));
  1289. end;
  1290.  
  1291.  
  1292. Function IsUserLoggedOn:boolean;
  1293. Var mask:byte;
  1294.     id:LongInt;
  1295.     objName:String;
  1296.     objType:word;
  1297. begin
  1298. IsUserLoggedOn:=( nwBindry.getBinderyAccessLevel(mask,id)
  1299.                   and (id<>0)
  1300.                   and nwBindry.GetBinderyObjectName(id,objName,objType)
  1301.                 )
  1302. end;
  1303.  
  1304.  
  1305. Function GetRealUserName(userObjName:string; Var realname:string):boolean;
  1306. Var propValue:Tproperty;
  1307.     moreSeg:Boolean;
  1308.     w,propFlag:Byte;
  1309. begin
  1310. If ReadPropertyValue(userObjName,OT_USER,'IDENTIFICATION',1,propValue,moreSeg,propFlag)
  1311.  then ZstrCopy(RealName,PropValue,128)
  1312.  else realname:='';
  1313. GetRealUserName:=(result=0);
  1314. end;
  1315.  
  1316. Function GetUserObjectID:LongInt;
  1317. Var mask:byte;
  1318.     id:LongInt;
  1319. begin
  1320. if getBinderyAccessLevel(mask,id)
  1321.  then GetUserObjectID:=id
  1322.  else getUserObjectID:=-1;
  1323. { -1 : look at nwBindry.result for error number }
  1324. end;
  1325.  
  1326.  
  1327. Function ExistsUser(userObjName:string):boolean;
  1328. Var ObjId:Longint;
  1329. begin
  1330. ExistsUser:=GetBinderyObjectId(userObjName,OT_USER,ObjId);
  1331. end;
  1332.  
  1333. Function IsGroupMember( GroupName,UserObjName:String): Boolean;
  1334. begin
  1335. IsGroupMember:=IsBinderyObjectInSet(GroupName,OT_USER_GROUP,'GROUP_MEMBERS',
  1336.                                     UserObjName,OT_USER);
  1337. end;
  1338.  
  1339.  
  1340.  
  1341.  
  1342. Function AddUserToGroup(userName,GroupName:String):boolean;
  1343. begin
  1344. { first create the necessary properties. They may already exist. }
  1345.  
  1346. CreateProperty(userName,OT_USER,'GROUPS_I''M_IN',
  1347.                BF_SET,BS_SUPER_WRITE OR BS_LOGGED_READ);
  1348. IF (result<>$00) and (result<>$ED) { property already exists }
  1349. then begin AddUserToGroup:=false;exit end; { bindery failure / bad username}
  1350.  
  1351. CreateProperty(userName,OT_USER,'SECURITY_EQUALS',
  1352.                BF_SET,BS_SUPER_WRITE OR BS_LOGGED_READ);
  1353. IF (result<>$00) and (result<>$ED) { property already exists }
  1354. then begin AddUserToGroup:=false;exit end;
  1355.  
  1356. { The following construction seems a bit overdone, but it is needed to keep
  1357.   the bindery consistent. A user is either fully added to a group OR
  1358.   nothing happens, this way we ensure that a user is not 'patially added'
  1359.   to a group.
  1360.   If the user already is a member of the group, no error is returned. }
  1361. IF AddBinderyObjectToSet(Groupname,OT_USER_GROUP,'GROUP_MEMBERS',
  1362.                          userName,OT_USER)
  1363.  then begin
  1364.       IF AddBinderyObjectToSet(userName,OT_USER,'GROUPS_I''M_IN',
  1365.                                GroupName,OT_USER_GROUP)
  1366.        then begin
  1367.             IF AddBinderyObjectToSet(userName,OT_USER,'SECURITY_EQUALS',
  1368.                                      GroupName,OT_USER_GROUP)
  1369.              then begin
  1370.                   AddUserToGroup:=true;
  1371.                   exit;
  1372.                   end
  1373.              else begin { attempt to delete partially setup member }
  1374.                   DeleteBinderyObjectFromSet(Groupname,OT_USER_GROUP,'GROUP_MEMBERS',
  1375.                                              userName,OT_USER);
  1376.                   DeleteBinderyObjectFromSet(userName,OT_USER,'GROUPS_I''M_IN',
  1377.                                              GroupName,OT_USER_GROUP)
  1378.                   end
  1379.             end
  1380.        else begin
  1381.             DeleteBinderyObjectFromSet(Groupname,OT_USER_GROUP,'GROUP_MEMBERS',
  1382.                                        userName,OT_USER);
  1383.             end;
  1384.       end;
  1385. if result=$E9 then result:=$00; { $E9: user already a member of group }
  1386. AddUserToGroup:=(result=0);
  1387. { As all these called functions are in this unit, you can check nwBindry.result
  1388.   for the errorcode. }
  1389. { resultcodes: $FC user OR group object doesn't exist. }
  1390. end;
  1391.  
  1392.  
  1393.  
  1394.  
  1395. Function DeleteUserFromGroup(userName,GroupName:String):boolean;
  1396. begin
  1397. { The following construction seems a bit overdone, but it is needed to keep
  1398.   the bindery consistent. A user is either totally deleted from a group OR
  1399.   nothing happens, this way we ensure that a user is not 'patially deleted'
  1400.   from a group.
  1401.   If the user was not a member of the group, no error is returned. }
  1402. IF DeleteBinderyObjectFromSet(Groupname,OT_USER_GROUP,'GROUP_MEMBERS',
  1403.                               userName,OT_USER)
  1404.  then begin
  1405.       IF DeleteBinderyObjectFromSet(userName,OT_USER,'GROUPS_I''M_IN',
  1406.                                     GroupName,OT_USER_GROUP)
  1407.        then begin
  1408.             IF DeleteBinderyObjectFromSet(userName,OT_USER,'SECURITY_EQUALS',
  1409.                                           GroupName,OT_USER_GROUP)
  1410.              then begin
  1411.                   DeleteUserFromGroup:=True;
  1412.                   exit;
  1413.                   end
  1414.              else begin { attempt to repair partially deleted member }
  1415.                   AddBinderyObjectToSet(Groupname,OT_USER_GROUP,'GROUP_MEMBERS',
  1416.                                         userName,OT_USER);
  1417.                   AddBinderyObjectToSet(userName,OT_USER,'GROUPS_I''M_IN',
  1418.                                         GroupName,OT_USER_GROUP)
  1419.                   end
  1420.             end
  1421.        else AddBinderyObjectToSet(Groupname,OT_USER_GROUP,'GROUP_MEMBERS',
  1422.                                   userName,OT_USER);
  1423.       end;
  1424. if result=$EA then result:=0; { $EA: user obj NOT a member of group }
  1425. DeleteUserFromGroup:=false;
  1426. { As all these called functions are in this unit, you can check nwBindry.result
  1427.   for the errorcode. }
  1428. { Resultcodes: $FC user OR group object doesn't exist.   }
  1429. end;
  1430.  
  1431. Function ExistsFileServer(ServerName:string):Boolean;
  1432. { You must be attached to at least one server before using this function. }
  1433. Var ObjId:Longint;
  1434. begin
  1435. UpString(ServerName);
  1436. ExistsFileServer:=GetBinderyObjectId(ServerName,OT_FILE_SERVER,ObjId);
  1437. end;
  1438.  
  1439.  
  1440.  
  1441. end. { end of unit nwBindry }
  1442.  
  1443.